class Gauge {
	constructor({
		canvasId,
		startAngle = 1 * Math.PI,
		endAngle = 0 * Math.PI,
		width = 200,
		min = 0,
		max = 100,
		value = 0,
		unit = '%',
		showTick = false,
		valueColor = '#555',
		progressColor = '',
		trackColor = '#F1F1F1',
		lineWidth = 10,
		btmText = "",
		bgImg = ''
	}) {
		this.ctx = uni.createCanvasContext(canvasId)
		this.startAngle = startAngle
		this.endAngle = endAngle
		this.width = width
		this.min = min
		this.max = max
		this.value = value
		this.unit = unit
		this.showTick = showTick
		this.valueColor = valueColor
		this.progressColor = progressColor
		this.trackColor = trackColor
		this.lineWidth = lineWidth
		this.btmText = btmText
		this.bgImg = bgImg
		this.radius = this.width / 2
		this.process = min || -1
		this.tickLength = this.max - this.min
		this.trackRadius = this.radius - this.lineWidth / 2
		this.tickRad = (2 * Math.PI - this.startAngle + this.endAngle) / this.tickLength
		this.start()
	}
	draw() {
		// 将坐标中心点移动到圆心位置
		this.ctx.fillStyle = "#FFFFFF";
		this.ctx.translate(this.radius, 200)
		this.drawBg()
		this.drawTrack()
		this.drawValueText()
		this.drawProgress()
		this.drawProgressBigRadio()
		this.drawProgressRadio()
		this.drawProgressTriangle()
		if (this.showTick) {
			this.drawTick()
			this.drawTickText()
		}
		this.ctx.draw()
		this.ctx.fillStyle = "#FFFFFF";
	}
	// 白色背景
	drawBg() {
		this.ctx.save()
		this.ctx.arc(0, 0, 170, 1 * Math.PI, 2 * Math.PI)
		this.ctx.fill()
		this.ctx.fillStyle = "#FFFFFF";
		this.ctx.restore()
	}
	// 轨迹圆环
	drawTrack() {
		this.ctx.save()
		this.ctx.beginPath()
		this.ctx.lineWidth = this.lineWidth
		this.ctx.lineJoin = 'round'
		this.ctx.lineCap = "round"
		this.ctx.strokeStyle = this.trackColor
		this.ctx.arc(0, 0, 150, this.startAngle, this.endAngle)
		this.ctx.stroke()
		this.ctx.restore()
	}
	// 当前值显示
	drawValueText() {
		this.ctx.save()
		this.ctx.fillStyle = this.valueColor
		this.ctx.font = "normal normal bolder 48px PingFangSC-Regular"
		this.ctx.textAlign = 'center'
		this.ctx.textBaseline = 'middle'
		this.ctx.fillText(`${this.value}${this.unit}`, 0, -50)
		this.ctx.restore()
	}
	// 进度圆环
	drawProgress() {
		this.ctx.save()
		const valueRad = this.getValueRad()
		this.ctx.beginPath()
		this.ctx.lineWidth = this.lineWidth
		this.ctx.strokeStyle = typeof this.progressColor === 'string' ? this.progressColor : this.getGradient(this
			.progressColor)
		this.ctx.lineJoin = 'round'
		this.ctx.lineCap = "round"
		// 终点角度是动态的
		this.ctx.arc(0, 0, 150, this.startAngle, valueRad)
		this.ctx.stroke()
		this.ctx.restore()
	}
	drawProgressRadio() {
		this.ctx.save()
		const valueRad = this.getValueRad()
		this.ctx.beginPath()
		this.ctx.lineWidth = this.lineWidth + 8
		var gradient = this.ctx.createLinearGradient(-170, 0, 170, 0);
		this.progressColor.forEach((color, index) => {
			gradient.addColorStop(index / (this.progressColor.length - 1), color)
		})
		this.ctx.strokeStyle = gradient
		this.ctx.lineJoin = 'round'
		this.ctx.lineCap = "round"
		// 终点角度是动态的
		this.ctx.arc(0, 0, 150, valueRad - 0.005, valueRad)
		this.ctx.stroke()
		this.ctx.restore()
	}
	drawProgressBigRadio() {
		this.ctx.save()
		const valueRad = this.getValueRad()
		this.ctx.beginPath()
		this.ctx.lineWidth = this.lineWidth + 14
		this.ctx.strokeStyle = "#fff";
		this.ctx.lineJoin = 'round'
		this.ctx.lineCap = "round"
		// 终点角度是动态的
		this.ctx.arc(0, 0, 150, valueRad - 0.005, valueRad)
		this.ctx.stroke()
		this.ctx.restore()
	}
	// 指示三角形
	drawProgressTriangle() {
		this.ctx.save()
		const valueRad = this.getValueRad()
		this.ctx.beginPath()
		this.ctx.lineWidth = this.lineWidth + 5
		let gra = this.ctx.createLinearGradient(-90, 0, 90, 0);
		this.progressColor.forEach((color, index) => {
			gra.addColorStop(index / (this.progressColor.length - 1), color)
		})
		this.ctx.strokeStyle = gra
		// this.ctx.lineCap = "square"
		// 终点角度是动态的
		this.ctx.arc(0, 0, 90, valueRad - 0.02, valueRad)
		this.ctx.stroke()
		this.ctx.restore()
	}
	// 刻度线
	drawTick() {
		// 不可是使用旋转，否则文字也会旋转
		let deg = this.startAngle
		for (let i = this.min; i <= this.max; i++) {
			this.ctx.save()
			this.ctx.lineWidth = this.ctx.strokeStyle = '#999'
			this.ctx.beginPath()
			// 刻度起点
			let x0 = (this.radius - this.lineWidth - 34) * Math.cos(deg)
			let y0 = (this.radius - this.lineWidth - 34) * Math.sin(deg)
			// 刻度终点
			var x1 = (this.radius - this.lineWidth - 28) * Math.cos(deg)
			var y1 = (this.radius - this.lineWidth - 28) * Math.sin(deg)
			this.ctx.moveTo(x0, y0)
			if ([0, 20, 40, 60, 80, 100].includes(i)) {
				this.ctx.lineTo(x1, y1)
			}
			deg += this.tickRad
			this.ctx.stroke()
			this.ctx.restore()
		}
	}
	// 刻度值
	drawTickText() {
		let deg = this.startAngle
		for (let i = this.min; i <= this.max; i++) {
			let x = (this.radius - this.lineWidth - 50) * Math.cos(deg)
			let y = (this.radius - this.lineWidth - 50) * Math.sin(deg)
			deg += this.tickRad
			if (this.bgImg) {
				this.ctx.drawImage(this.bgImg, -83, -24, 166, 24)
			}
			this.ctx.save()
			this.ctx.font = 'normal normal 600 12px PingFangSC-Regular'
			this.ctx.fillStyle = '#0E0E0E'
			this.ctx.textAlign = 'center'
			this.ctx.fillText(`${this.btmText}`, 0, -8);
			// 不设置会与tick错位
			this.ctx.textBaseline = 'middle'
			if ([0, 20, 40, 60, 80, 100].includes(i)) {
				this.ctx.fillText(i, x, y)
			}
			this.ctx.restore()
		}
	}
	// 当前值的弧度
	getValueRad() {
		// 超出
		if (this.value > this.max) {
			return (this.max - this.min) * this.tickRad + this.startAngle
		}
		return (this.process - 4 - this.min) * this.tickRad + this.startAngle
	}
	start() {
		let update = () => {
			this.process = this.process + 5
			if (this.process > this.value + 5) {
				uni.cancelAnimationFrame(update)
			} else {
				this.draw()
				uni.requestAnimationFrame(update)
			}
		}
		uni.requestAnimationFrame(update);
	}
	// 渐变
	getGradient(colorList) {
		let grd = this.ctx.createLinearGradient(-170, 0, 170, 0)
		colorList.forEach((color, index) => {
			grd.addColorStop(index / (colorList.length - 1), color)
		})
		return grd
	}
}
uni.requestAnimationFrame = function(callback) {
	var lastTime = 0;
	var currTime = new Date().getTime();
	var timeToCall = Math.max(0, 16 - (currTime - lastTime));
	var id = setTimeout(function() {
		callback(1);
	}, 70);
	lastTime = currTime + timeToCall;
	return id;
};
uni.cancelAnimationFrame = function(id) {
	clearTimeout(id);
};
(function() {
	var lastTime = 0;
	var vendors = ['webkit', 'moz', 'ms', 'o'];
	for (var x = 0; x < vendors.length && !uni.requestAnimationFrame; ++x) {
		uni.requestAnimationFrame = uni[vendors[x] + 'RequestAnimationFrame'];
		uni.cancelAnimationFrame = uni[vendors[x] + 'CancelAnimationFrame'] || uni[vendors[x] +
			'CancelRequestAnimationFrame'];
	}
	if (!uni.requestAnimationFrame) uni.requestAnimationFrame = function(callback) {
		return setTimeout(callback, 50);
	};
	if (!uni.cancelAnimationFrame) uni.cancelAnimationFrame = function(id) {
		clearTimeout(id);
	};
})();
export default Gauge